package net.wofly.sale.stock.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.alibaba.druid.util.StringUtils;

import net.wofly.framework.util.Identities;
import net.wofly.framework.util.ReturnBean;
import net.wofly.right.domain.User;
import net.wofly.right.service.IUserService;
import net.wofly.sale.stock.domain.InOutStockDetail;
import net.wofly.sale.stock.domain.InStock;
import net.wofly.sale.stock.domain.OutStock;
import net.wofly.sale.stock.domain.ResourceAsk;
import net.wofly.sale.stock.domain.ResourceAskList;
import net.wofly.sale.stock.domain.Stock;
import net.wofly.sale.stock.domain.Warehouse;
import net.wofly.sale.stock.repository.InStockRepository;
import net.wofly.sale.stock.service.IInStockService;
import net.wofly.sale.stock.service.IOutStockService;
import net.wofly.sale.stock.service.IStockService;
import net.wofly.sale.stock.service.IWarehouseService;
import net.wofly.sale.stock.util.InStockType;
import net.wofly.sale.stock.util.OutStockType;

@Service("iInStockService")
@Transactional
public class InStockServiceImpl implements IInStockService {

	@Autowired
	InStockRepository inStockRepository;
	
	@Autowired
	IUserService iUserService;
	
	@Autowired
	IStockService iStockService;
	
	@Autowired
	IOutStockService iOutStockService;
	
	@Autowired
	IWarehouseService iWarehouseService;

	@Override
	public InStock save(InStock entity) {
		return inStockRepository.save(entity);
	}

	@Override
	public void delete(InStock entity) {
		inStockRepository.delete(entity);
	}

	@Override
	public void delete(String key) {
		inStockRepository.delete(key);
	}

	@Override
	public InStock findOne(String key) {
		return inStockRepository.findOne(key);
	}
	
	@Override
	public Page<InStock> findAll(Specification specification, Pageable pageable) {
		return inStockRepository.findAll(specification, pageable);
	}
	
	@Override
	public List<InStock> save(List<InStock> entityList) {
		return (List<InStock>) inStockRepository.save(entityList);
	}
	
	private ReturnBean<String> inStockFromResourceAskForCompanny(ResourceAsk ra ,User user) {
		Long exeTime = System.currentTimeMillis() ;
		
		//申请人库存  领料加到申请人库存上
		List<Stock> askerStocks = iStockService.findByWarehouseID(user.getWarehouseID()) ;
		//申请人库存变更
		List<Stock> askerChangeStocks = new ArrayList<>() ;
		Map<String ,Stock> askerStockMap = new HashMap<>() ;
		for(Stock stock:askerStocks) {
			askerStockMap.put(stock.getCommodityTerminalID(), stock) ;
		}
		
		InStock askerInStock = new InStock() ;
		askerInStock.setInStockID(Identities.uuid2());
		askerInStock.setWarehouseID(user.getWarehouseID());
		askerInStock.setProofID(ra.getResourceAskID());
		askerInStock.setInStockType(InStockType.领料单.getValue());
		askerInStock.setInStocker(ra.getAsker());
		askerInStock.setModifyDate(exeTime);
		
		List<InOutStockDetail> askerInOutStockDetails = new ArrayList<>() ;
		InOutStockDetail askerInOutStockDetail ;
		Stock tmpAskerStock ;
		
		for (ResourceAskList resourceAskList: ra.getResourceAskLists()) {
			
			//处理申请人入库流水
			askerInOutStockDetail = new InOutStockDetail() ;
			askerInOutStockDetail.setInOutStockDetailID(Identities.uuid2());
			askerInOutStockDetail.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			askerInOutStockDetail.setNum(resourceAskList.getAskNum());
			askerInOutStockDetail.setOperateStockID(askerInStock.getInStockID());
			askerInOutStockDetail.setOperationType(1);
			askerInOutStockDetail.setModifyDate(exeTime);
			askerInOutStockDetails.add(askerInOutStockDetail) ;
			
			//处理申请人库存
			tmpAskerStock = askerStockMap.get(resourceAskList.getCommodityTerminalID()) ;
			if (null == tmpAskerStock) {
				tmpAskerStock = new Stock() ;
				tmpAskerStock.setStockID(Identities.uuid2());
				tmpAskerStock.setWarehouseID(user.getWarehouseID()) ;
				tmpAskerStock.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			}
			tmpAskerStock.setNum(tmpAskerStock.getNum() + resourceAskList.getAskNum());
			tmpAskerStock.setModifyDate(exeTime);
			askerChangeStocks.add(tmpAskerStock) ;
		}
		
		askerInStock.setInOutStockDetails(askerInOutStockDetails);
		
		iStockService.save(askerChangeStocks) ;
		inStockRepository.save(askerInStock) ;
		
		return new ReturnBean<>(0, "通过领料单入库成功。") ;
	}
	
	private ReturnBean<String> inStockFromResourceAskForPersonal(ResourceAsk ra ,User user ,Warehouse companyWarehouse) {
		Long exeTime = System.currentTimeMillis() ;
		
		//公司库存 所有领料申请都要减公司库存，但申请人库存为公司库存时，不减公司库存
		List<Stock> companyStocks = iStockService.findByWarehouseID(companyWarehouse.getWarehouseID()) ;
		//公司库存变更
		List<Stock> companyChangeStocks = new ArrayList<>() ;
		Map<String ,Stock> companyStockMap = new HashMap<>() ;
		for(Stock stock:companyStocks) {
			companyStockMap.put(stock.getCommodityTerminalID(), stock) ;
		}
		
		//申请人库存  领料加到申请人库存上
		List<Stock> askerStocks = iStockService.findByWarehouseID(user.getWarehouseID()) ;
		//申请人库存变更
		List<Stock> askerChangeStocks = new ArrayList<>() ;
		Map<String ,Stock> askerStockMap = new HashMap<>() ;
		for(Stock stock:askerStocks) {
			askerStockMap.put(stock.getCommodityTerminalID(), stock) ;
		}
		
		InStock askerInStock = new InStock() ;
		askerInStock.setInStockID(Identities.uuid2());
		askerInStock.setWarehouseID(user.getWarehouseID());
		askerInStock.setProofID(ra.getResourceAskID());
		askerInStock.setInStockType(InStockType.领料单.getValue());
		askerInStock.setInStocker(ra.getAsker());
		askerInStock.setModifyDate(exeTime);
		
		OutStock companyOutStock = new OutStock() ;
		companyOutStock.setOutStockID(Identities.uuid2());
		companyOutStock.setWarehouseID(companyWarehouse.getWarehouseID());
		companyOutStock.setProofID(ra.getResourceAskID());
		companyOutStock.setOutStockType(OutStockType.领料单.getValue());
		companyOutStock.setOutStocker(ra.getAsker());
		companyOutStock.setModifyDate(exeTime);
		
		List<InOutStockDetail> askerInOutStockDetails = new ArrayList<>() ;
		List<InOutStockDetail> companyInOutStockDetails = new ArrayList<>() ;
		InOutStockDetail askerInOutStockDetail ;
		InOutStockDetail companyInOutStockDetail ;
		Stock tmpAskerStock ;
		Stock tmpCompanyStock ;
		
		for (ResourceAskList resourceAskList: ra.getResourceAskLists()) {
			
			//处理申请人入库流水
			askerInOutStockDetail = new InOutStockDetail() ;
			askerInOutStockDetail.setInOutStockDetailID(Identities.uuid2());
			askerInOutStockDetail.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			askerInOutStockDetail.setNum(resourceAskList.getAskNum());
			askerInOutStockDetail.setOperateStockID(askerInStock.getInStockID());
			askerInOutStockDetail.setOperationType(1);
			askerInOutStockDetail.setModifyDate(exeTime);
			askerInOutStockDetails.add(askerInOutStockDetail) ;
			
			//处理申请人库存
			tmpAskerStock = askerStockMap.get(resourceAskList.getCommodityTerminalID()) ;
			if (null == tmpAskerStock) {
				tmpAskerStock = new Stock() ;
				tmpAskerStock.setStockID(Identities.uuid2());
				tmpAskerStock.setWarehouseID(user.getWarehouseID()) ;
				tmpAskerStock.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			}
			tmpAskerStock.setNum(tmpAskerStock.getNum() + resourceAskList.getAskNum());
			tmpAskerStock.setModifyDate(exeTime);
			askerChangeStocks.add(tmpAskerStock) ;
			
			tmpCompanyStock = companyStockMap.get(resourceAskList.getCommodityTerminalID()) ;
			if (null ==tmpCompanyStock) {
				tmpCompanyStock  = new Stock() ;
				tmpCompanyStock.setStockID(Identities.uuid2());
				tmpCompanyStock.setWarehouseID(companyWarehouse.getWarehouseID()) ;
				tmpCompanyStock.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			}
			tmpCompanyStock.setNum(tmpCompanyStock.getNum() - resourceAskList.getAskNum());
			tmpCompanyStock.setModifyDate(exeTime);
			companyChangeStocks.add(tmpCompanyStock) ;
			
			//处理公司出库流水
			companyInOutStockDetail = new InOutStockDetail() ;
			companyInOutStockDetail.setInOutStockDetailID(Identities.uuid2());
			companyInOutStockDetail.setCommodityTerminalID(resourceAskList.getCommodityTerminalID());
			companyInOutStockDetail.setNum(resourceAskList.getAskNum());
			companyInOutStockDetail.setOperateStockID(companyOutStock.getOutStockID());
			companyInOutStockDetail.setOperationType(2);
			companyInOutStockDetail.setModifyDate(exeTime);
			companyInOutStockDetails.add(companyInOutStockDetail) ;
			
		}
		
		askerInStock.setInOutStockDetails(askerInOutStockDetails);
		companyOutStock.setInOutStockDetails(companyInOutStockDetails);
		
		iStockService.save(askerChangeStocks) ;
		inStockRepository.save(askerInStock) ;
		
		iStockService.save(companyChangeStocks) ;
		iOutStockService.save(companyOutStock) ;
		
		return new ReturnBean<>(0, "通过领料单入库成功。") ;
	}

	@Override
	public ReturnBean<String> inStockFromResourceAsk(ResourceAsk ra) {
		User user =  iUserService.findOne(ra.getAsker()) ;
		
		if (null == user) {
			return new ReturnBean<>(5011, "领料申请人不存在！无法更新为库存") ;
		}
		
		if (StringUtils.isEmpty(user.getWarehouseID())) {
			return new ReturnBean<>(5012, "领料申请人没有仓库信息，请与管理员联系，并配上仓库信息。") ;
		}
		
		List<Warehouse> warehouses = iWarehouseService.findByWarehouseTypeAndStatus("1", 1) ;	//公司总库
		Warehouse companyWarehouse ;
		if (warehouses.isEmpty()) {
			return new ReturnBean<>(5013, "没有公司仓库信息，请与管理员联系，并配上仓库信息。") ;
		}
		
		companyWarehouse = warehouses.get(0) ;
		
		if (user.getWarehouseType().equals(1)) {
			inStockFromResourceAskForCompanny(ra , user) ;
		}else {
			inStockFromResourceAskForPersonal(ra , user , companyWarehouse) ;
		}
		
		return new ReturnBean<>(0, "通过领料单入库成功。") ;
	}
	
	
}
